package fybug.nulll.pdstream.WR;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;

import fybug.nulll.pdstream.Source.StreamSource;
import fybug.nulll.pdstream.WR.Stream.CopyChar;
import fybug.nulll.pdstream.WR.Stream.Read;
import fybug.nulll.pdstream.WR.Stream.Write;
/**
 * <h2><b>字符流</b> 操作器工场类.</h2>
 * <pre>
 * 可以使用 <b>字节流</b> 构建操作器，但需要传入 <b>字符编码</b>
 * 可以使用 <b>路径</b> 构建操作器，也需要传入 <b>字符编码需</b> ,而且要你自己处理{@link FileNotFoundException}
 * 包含:
 * {@link #reader(Reader)} 构造读取器
 * {@link #writer(Writer, String)} 构造写入器
 * {@link #copy(Writer, Reader)} 构造复制器
 * </pre>
 *
 * @author fybug
 * @version 0.0.4
 * @see Read
 * @see Write
 * @see CopyChar
 * @see StreamSource.Strings
 * @since JDK 1.8
 */
@SuppressWarnings( "all" )
public final
class W_R {
    /** {@Hide} */
    @Deprecated
    private
    W_R() {}

    /*
     * Read
     */

    /**
     * <p>构造一个 <b>字符流</b> 读取器.</p>
     *
     * @param reader 要读取的流
     *
     * @return 读取器
     */
    @NotNull
    public static
    Read reader(@Nullable final Reader... reader)
    { return new Read(StreamSource.Strings.reader(reader)); }

    /**
     * <p>使用 <b>字节流</b> 构造一个 <b>字符流</b> 读取器.</p>
     * <p>需传入所使用的 <b>字符编码</b>
     *
     * @param inputStream 要读取的流
     * @param charname    用于转化的字符编码
     *
     * @return 读取器
     */
    @NotNull
    public static
    Read reader(@NotNull final String charname, @Nullable final InputStream... inputStream)
    { return new Read(StreamSource.Strings.reader(charname, inputStream)); }

    /**
     * <p>构造一个文本文件读取器.</p>
     * <p>需传入所使用的 <b>字符编码</b></p>
     *
     * @param inputStream 要读取的文件
     * @param charname    字符编码
     *
     * @return 读取器
     */
    @NotNull
    public static
    Read reader(@NotNull final String charname, @Nullable final File... inputStream)
    { return new Read(StreamSource.Strings.reader(charname, inputStream)); }

    /*
     * Write
     */

    /**
     * <p>构造一个 <b>字符流</b> 写入器.</p>
     * <p>需传入要写入的字符串</p>
     *
     * @param writer 要输出的流
     * @param s      要输出的内容
     *
     * @return 写入器
     */
    @NotNull
    public static
    Write writer(@Nullable final Writer writer, @Nullable final String s)
    { return new Write(StreamSource.Strings.writer(writer, s)); }

    /**
     * <p>构造一个 <b>字符流</b> 写入器.</p>
     * <p>需传入要写入的字符串</p>
     *
     * @param writer 要输出的流
     * @param s      要输出的内容
     *
     * @return 写入器
     */
    @NotNull
    public static
    Write writer(@Nullable final Writer[] writer, @Nullable final String s)
    { return new Write(StreamSource.Strings.writer(writer, s)); }

    /**
     * <p>使用 <b>字节流</b> 构造一个 <b>字符流</b> 写入器.</p>
     * <p>需传入所使用的 <b>字符编码</b> 和要写入的字符串</p>
     *
     * @param writer   要输出的流
     * @param charname 转化用的字符编码
     * @param s        要输出的内容
     *
     * @return 写入器
     */
    @NotNull
    public static
    Write writer(@NotNull final String charname, @Nullable final OutputStream writer,
            @Nullable final String s)
    { return new Write(StreamSource.Strings.writer(charname, writer, s)); }

    /**
     * <p>使用 <b>字节流</b> 构造一个 <b>字符流</b> 写入器.</p>
     * <p>需传入所使用的 <b>字符编码</b> 和要写入的字符串</p>
     *
     * @param writer   要输出的流
     * @param charname 转化用的字符编码
     * @param s        要输出的内容
     *
     * @return 写入器
     */
    @NotNull
    public static
    Write writer(@NotNull final String charname, @Nullable final OutputStream[] writer,
            @Nullable final String s)
    { return new Write(StreamSource.Strings.writer(charname, writer, s)); }

    /**
     * <p>构造一个文本文件写入器.</p>
     * <p>需传入所使用的 <b>字符编码</b> 和要写入的字符串</p>
     *
     * @param writer   要输出的文件
     * @param charname 转化用的字符编码
     * @param s        要写入的内容
     *
     * @return 写入器
     */
    @NotNull
    public static
    Write writer(@NotNull final String charname, @Nullable final File writer,
            @Nullable final String s) throws FileNotFoundException
    { return new Write(StreamSource.Strings.writer(charname, writer, s)); }

    /**
     * <p>构造一个文本文件写入器.</p>
     * <p>需传入所使用的 <b>字符编码</b> 和要写入的字符串</p>
     *
     * @param writer   要输出的文件
     * @param charname 转化用的字符编码
     * @param s        要写入的内容
     *
     * @return 写入器
     */
    @NotNull
    public static
    Write writer(@NotNull final String charname, @Nullable final File[] writer,
            @Nullable final String s) throws FileNotFoundException
    { return new Write(StreamSource.Strings.writer(charname, writer, s)); }

    /*
     * Copy
     */

    /**
     * <p>构造一个 <b>字符流</b> 复制器.</p>
     * <p>需传入 <b>被复制流</b></p>
     *
     * @param copyfrom 复制该流中的内容
     * @param copyto   复制到该流
     *
     * @return 复制器
     */
    @NotNull
    public static
    CopyChar copy(@Nullable final Writer copyto, @Nullable final Reader copyfrom)
    { return new CopyChar(StreamSource.Strings.copy(copyto, copyfrom)); }

    /**
     * <p>构造一个批量字符复制器.</p>
     * <p>需传入 <b>被复制流</b></p>
     *
     * @param copyfrom 复制该流中的内容
     * @param copyto   复制到该流
     *
     * @return 复制器
     */
    @NotNull
    public static
    CopyChar copy(@Nullable final Writer[] copyto, @Nullable final Reader[] copyfrom)
    { return new CopyChar(StreamSource.Strings.copy(copyto, copyfrom)); }

    /**
     * <p>使用字符集合作为被复制源构造一个 <b>字符流</b> 复制器.</p>
     * <p>需传入 <b>被复制流</b></p>
     *
     * @param copyfrom 复制该流中的内容
     * @param copyto   复制到该流
     *
     * @return 复制器
     */
    @NotNull
    public static
    CopyChar copy(@Nullable final Writer copyto, @Nullable final CharSequence copyfrom)
    {
        return new CopyChar(
                StreamSource.Strings.copy(copyto, new StringReader(copyfrom.toString())));
    }

    /**
     * <p>使用字符集合作为被复制源构造一个批量字符复制器.</p>
     * <p>需传入 <b>被复制流</b></p>
     *
     * @param copyfrom 复制该流中的内容
     * @param copyto   复制到该流
     *
     * @return 复制器
     */
    @NotNull
    public static
    CopyChar copy(@Nullable final Writer[] copyto, @Nullable final CharSequence copyfrom)
    {
        return new CopyChar(StreamSource.Strings.copy(copyto, new Reader[]{
                new StringReader(copyfrom.toString())}));
    }

    /**
     * <p>使用 <b>字节流</b> 构造一个 <b>字符流</b> 复制器.</p>
     * <p>需传入 <b>被复制流</b> 和所使用的 <b>字符编码</b></p>
     *
     * @param copyfrom 复制该流中的内容
     * @param copyto   复制到该流
     * @param charname 转化用的字符编码
     *
     * @return 复制器
     */
    @NotNull
    public static
    CopyChar copy(@NotNull final String charname, @Nullable final OutputStream copyto,
            @Nullable final InputStream copyfrom)
    { return new CopyChar(StreamSource.Strings.copy(charname, copyto, copyfrom)); }
}
